#ifndef UTILS_H
#define UTILS_H
/**
 * @class SimpleArray template, designed to be more efficient than std::vector for my particular use
 */
template<typename _type, int extent, typename _countType=int> class SimpleArray
{
public:
//    _countType  _count;
    struct hdr { size_t _count; _type* _data; };
    hdr* _raw;
public:
    SimpleArray():/*_count(0),*/ _raw(NULL) {}
    _countType count() const { return _raw==NULL?0:_raw->_count; }
    _type* begin() {return _raw==NULL?0:_raw->_data; }
    const _type* begin() const {return _raw==NULL?0:_raw->_data; }
    _type& back() { return _raw->_data[_raw->_count-1]; }
    const _type& back() const { return _raw->_data[_raw->_count-1]; }
    _type* end() { return _raw==NULL?NULL:_raw->_data+_raw->_count; }
    const _type* end() const { return _raw==NULL?NULL:_raw->_data+_raw->_count; }
    _type& operator [](int index) { return _raw->_data[index]; }
    const _type& operator [](int index)  const { return _raw->_data[index]; }
    void clear() { resize(0); }
    _type&	pushBack()
    {
        resize(count()+1); //make (empty) room
        return back();
    }
    _type&	pushBack(_type& elt)
    {
        _type& _back = pushBack();
        _back = elt;
        return _back;
    }
    _countType size() const { return count(); }
    _countType memSize() const { return count() * sizeof(_type); }
    size_t reserved() const { size_t _count = count(); return ((_count & (extent-1)) != 0?(_count & (~(extent-1)))+extent:_count); }
    size_t allocated() const { return reserved() * sizeof(_type); }
    void resize(int newCount)
    {
        //_type* old = _data;
        size_t size = reserved();
        if (newCount > size)
        {
            size = newCount;
            if (size & (extent-1)!=0)
                size = (newCount & (~(extent-1)))+extent;
            if (_raw != NULL)
            {
                _raw = (hdr*)realloc(_raw, size * sizeof(_type) + sizeof(hdr));
                _raw->_data = (_type*)(_raw+1);
            }
            if (_raw==NULL)
            {
                hdr* old = _raw;
                _raw = (hdr*)malloc(size * sizeof(_type) + sizeof(hdr));
                if (_raw == NULL)
                {
                    //assert(false);
                    return;
                }
                _raw->_data = (_type*)(_raw+1);
                if (old)
                {
                    size_t count = old->_count;
                    if (count>size)
                        count = size;
                    memcpy(_raw->_data, old->_data, count * sizeof(_type));
                    free(old);
                }
            }
        }
        if (newCount==0)
        {
            if ((size>0)&&(_raw != NULL))
            {
                free(_raw);
                _raw = NULL;
            }
            return;
        }
        _raw->_count = newCount;
    }
};


static inline void sleepMs(int ms)
{
    Sleep(ms);
}


#endif // UTILS_H
